(function($) {
	var __bind = function(fn, me) {
		return function() {
			return fn.apply(me, arguments);
		};
	};
	DragProxy.prototype.defaults = {
		container : null, //jquery对象
		dragItem : null, //jquery对象
		moveItem : null, //jquery对象
		placeHolder : null, //jquery对象或字符串
		dragging : false,
		setPos : null,//函数
		index : 0
	};

	DragProxy.prototype.drag = function(e) {
		// 排除非左击和表单元素
		if (e.which != 1 || $(e.target).is("input, textarea")
				|| this.opts.dragging)
			return;
		
		
		// 阻止选中文本
		e.preventDefault();
		var dragItem = this.getDragItem();
		//需要验证是否绑定了dragStart
		var result = dragItem.triggerHandler("dragStart");
		if (result === false){
			return;
		}

		//设置正在拖拽中
		this.opts.dragging = true;

		
		//记录拖拽目标的起始位置
		var ofs = dragItem.offset();

		//记录状态,被拖拽的偏移量，和拖拽的鼠标位置
		this.dragLeft = ofs.left;
		this.dragTop = ofs.top;
		this.dragX = e.pageX;
		this.dragY = e.pageY;

		var placeHodler = this.opts.placeHolder;
		if (typeof placeHodler == 'string') {
			placeHodler = $(placeHodler);
			this.opts.placeHolder = placeHodler;
		}

		//被移动的对象
		var moveItem = this.getMoveItem();
		placeHodler.css({
			"height" : moveItem.outerHeight(true) - 4,
			"width" : moveItem.outerWidth(true),
			"border" : "2px dashed #ccc"
		});
		//将placeHolder放在被移动的位置
		moveItem.before(placeHodler);

		//设置被移动的对象，根据鼠标移动而移动
		// 保持原来的宽高
		moveItem.css({
			"width" : moveItem.width(),
			"height" : moveItem.height(),
			"position" : "absolute",
			"opacity" : 0.8,
			"z-index" : 999,
			"left" : this.dragLeft,
			"top" : this.dragTop
		});

		// 绑定拖拽移动和最后确定的落下的事件
		$(document).mousemove(__bind(this.moving, this));

		$(document).mouseup(__bind(this.drop, this));
	};

	DragProxy.prototype.moving = function(e) {
		e.preventDefault();
		var mx = e.pageX;
		var my = e.pageY;
		var ml = this.dragLeft + mx - this.dragX;
		var mt = this.dragTop + my - this.dragY;

		//被移动的对象
		var moveItem = this.getMoveItem();
		//设置移动块得位置

		var marginTop = parseInt(moveItem.css("marginTop"));
		var marginLeft = parseInt(moveItem.css("marginLeft"));

//		log("ml:" + ml + ",mt:" + mt + ",marginLeft:" + marginLeft
//				+ ",marginTop:" + marginTop);
		moveItem.css({
			left : ml,
			top : mt
		});
		var _t = this;
//		log2("pl:" + _t.opts.placeHolder.offset().left + ",pt:"
//				+ _t.opts.placeHolder.offset().top + ",ml:"
//				+ _t.opts.moveItem.offset().left + ",mt:"
//				+ _t.opts.moveItem.offset().top);
		var dragItem = this.getDragItem();
		//被拖拽对象的中心点，根据中心点的落在的位置来确认
		var dcx = ml + dragItem.width() / 2;
		var dcy = mt + dragItem.height() / 2;

		//设置placeHolder的位置
		this.setPlaceHolder(dcx, dcy);
	};

	DragProxy.prototype.setPlaceHolder = function(x, y) {
		var setPos = this.opts.setPos;
		if (setPos && typeof setPos == 'function') {
			setPos.call(this, x, y);
		}
	};

	DragProxy.prototype.drop = function(e) {
		$(document).off("mouseup").off("mousemove");
		var placeHolder = this.opts.placeHolder;
		var e = placeHolder.offset();
		var moveItem = this.getMoveItem();
		var _this = this;
		moveItem.animate({
			left : e.left,
			top : e.top
		}, 100, function() {
			moveItem.removeAttr("style");
			placeHolder.replaceWith(moveItem);
			_this.opts.dragging = false;
			var dragItem = _this.getDragItem();
			dragItem.css({
				cursor : "move"
			});
			dragItem.triggerHandler("dropEnd");
		});
	};

	DragProxy.prototype.enableDrag = function(enable) {
		var dragItem = this.opts.dragItem;
		if (enable) {
			//设置拖拽的鼠标样式
			dragItem.css({
				cursor : "move"
			});
			//绑定拖拽事件
			dragItem.off("mousedown").mousedown(__bind(this.drag, this));
		} else {
			//设置拖拽的鼠标样式
			dragItem.css({
				cursor : "pointer"
			});
			dragItem.off("mousedown");
		}
	};

	DragProxy.prototype.getMoveItem = function() {
		return this.opts.moveItem;
	};

	DragProxy.prototype.getDragItem = function() {
		return this.opts.dragItem;
	};

	function DragProxy(options) {
		this.opts = $.extend({}, this.defaults, options);
		if (!this.opts.moveItem) {
			this.opts.moveItem = this.opts.dragItem;
		}

		this.enableDrag(options.dragable);
	};

	$.fn.tablesort = function(opts) {
		function _setCellPos(x, y) {
			var c = this.opts.container;
			var o = this.opts;
			var _t = this;
			var rowBody;
			//找到单元格所在的行
			c.find(opts.rowBodySelector).each(function(i) {
				var curItem = $(this);
				var sx = curItem.offset().left;
				var ex = sx + curItem.width();
				var sy = curItem.offset().top;
				var ey = sy + curItem.height();
				if (sx < x && x < ex && sy < y && y < ey) {
					rowBody = curItem;
					return false;
				}
			});
			var placeHolder = this.opts.placeHolder;
			if (rowBody) {
				var children = rowBody.find(opts.itemSelector);

				//当前没有一个元素，则直接追加在该行后面
				if (children.length == 0) {
					rowBody.append(placeHolder);
				} else if (children.length == 2 && children.is(placeHolder)) {
					//如果该行，只有两个元素，一个被拖拽的元素，一个是placeHolder，则不需要处理
					return;
				} else {
					//寻找放置的位置
					var moveItem = this.opts.moveItem;
					var posItem;
					children.not(moveItem).each(function() {
						var curItem = $(this);
						var sx = curItem.offset().left;
						var ex = sx + curItem.width();
						var sy = curItem.offset().top;
						var ey = sy + curItem.height();
						if (sx < x && x < ex && sy < y && y < ey) {
							posItem = curItem;
							return false;
						}
					});
					if (posItem) {
						var nextItem = posItem.next();
						//如果该元素的后面没有元素，或者不是placeHolder
						if (nextItem.length == 0 || !nextItem.is(placeHolder)) {
							posItem.after(placeHolder);
						} else {
							posItem.before(placeHolder);
						}
					} else {
						rowBody.append(placeHolder);
					}
				}
			}
		}

		function _setRowPos(x, y) {
			var c = this.opts.container;
			var placeHolder = this.opts.placeHolder;
			var moveItem = this.opts.moveItem;
			c.find(opts.rowHeadSelector).not(this.opts.dragItem).each(
					function(i) {
						var curItem = $(this);
						var sx = curItem.offset().left;
						var ex = sx + curItem.width();
						var sy = curItem.offset().top;
						var ey = sy + curItem.height();
						var nextItem = curItem.next();
						//log("select:"+curItem.text()+"{x="+x+",y="+y+"},{x=("+sx+","+ex+"),y=("+sy+","+ey+")");
						if (sx < x && x < ex && sy < y && y < ey) {
							var nextItem = curItem.parent().next();
							//log(nextItem.is(placeHolder)+","+nextItem.is(moveItem)+",nextItem"+nextItem.);
							if (nextItem.is(placeHolder)) {
								curItem.parent().before(placeHolder);
							} else {
								curItem.parent().after(placeHolder);
							}
						}
					});
		}

		var c = this;
		//初始化单元格的拖拽功能

		var rows = [];
		var cells = [];

		c.find(opts.itemSelector).each(function(index) {
			var di = $(this);
			di.attr("data-cell-index", index);
			var drag = new DragProxy({
				container : c,
				dragItem : di,
				placeHolder : opts.itemPlaceHolder,
				setPos : _setCellPos,
				dragable : true,
				index : index
			});
			cells.push(drag);
		});
		//初始化行的拖拽功能
		c.find(opts.rowHeadSelector).each(function(index) {
			var di = $(this);
			di.attr("data-row-index", index);
			var drag = new DragProxy({
				container : c,
				dragItem : di,
				moveItem : di.parent(),
				placeHolder : opts.rowPlaceHolder,
				setPos : _setRowPos,
				dragable : false,
				index : index
			});
			//drag.dragItem.attr("data-row-index",index);
			rows.push(drag);
		});
		return {
			rows : rows,
			cells : cells,
			getRow:function(indexID){
				return this.rows[indexID];
			},
			getRowByDragItem : function(dragItem){
				var indexID = dragItem.attr("data-row-index");
				return this.getRow(indexID);
			},
			bindForRow : function(type, fn) {
				var _t = this;
				$.each(this.rows, function(index, row) {
					var dragItem = row.getDragItem();
					dragItem.bind(type, function() {
						return fn(_t, row);
					});
				});
				return this;
			},

			bindForCells : function(type, fn) {
				var _t = this;
				$.each(this.cells, function(index, cell) {
					var dragItem = cell.getDragItem();
					dragItem.bind(type, function() {
						return fn(_t, cell);
					});
				});
				return this;
			},
			getCellIndexID : function(cell) {
				var dragItem = cell.getDragItem();
				if (dragItem.attr("data-cell-index")) {
					return dragItem.attr("data-cell-index");
				}
			},
			getRowIndexID : function(row) {
				var dragItem = row.getDragItem();
				if (dragItem.attr("data-row-index")) {
					return dragItem.attr("data-row-index");
				}
			},
			findRow : function(cell) {
				//设置
				var dragItem = cell.getDragItem();
				if (dragItem.attr("data-cell-index")) {
					var row = dragItem.closest(opts.rowBodySelector).prev(
							opts.rowHeadSelector);
					var rowIndex = row.attr("data-row-index");
					if (rowIndex) {
						return this.rows[rowIndex];
					}
				}
			}

		};
	};
	$.fn.tablesort.defaults = {
		itemSelector : "",
		rowBodySelector : "",
		rowHeadSelector : "",
		itemPlaceHolder : "",
		rowPlaceHolder : ""
	};
})(jQuery);